import { MessageBoxService, GrowlMessageType, OperationLock, HandleExpectionErrorUseGrowMessage, MessageResult, Debounce, Throttle } from './../../components/messageBox';
import { PrinterManager } from './../../utils/print/printer/printManager';
import { PrintComponentService } from './../print/templates/printcontainer.component';
import { StoreSvr } from './../../services/store';
import { YScrollableContainer } from './../../components/y-scrollable-container';
import { NavigateService } from './../../services/navigate';
import { FNCManager, KdsMessageType } from './../../utils/fnc/fncManager';
import { AppStore } from './../../services/appStore';
import { ExpeditionOrderItem, ExpeditionOrder } from './../../models/expeditionOrder';
import { ExpeditionOrderDishManage } from './../../components/expeditionOrderDishManage';
import { Observable, Subscription } from 'rxjs';
import { Component, OnInit, Input, ChangeDetectorRef, ViewChild, OnDestroy, OnChanges, Output, EventEmitter } from '@angular/core';
import { groupBy } from 'ramda';
import { MapToIterable } from './../../utils/pipes/date';
import * as delay from "delay";
import * as JsBarcode from "jsbarcode";
import * as lodash from "lodash";

@Component({
    selector: 'deliver-orders',
    styleUrls: ['./index.scss'],
    template: `
        <div class="order_box check_out">
            <div *ngIf="!expedited"  class="top">
                <span class="order_title">出品盘 {{!expedited&&zoneName&&" + "}}</span>
                <div class="order_info">
                   <span>出品单号  </span><span style="padding-left: 10px;" class="order_name">{{expeditionOrder&&expeditionOrder.serialNo}}</span>
                </div>
            </div>
            <div *ngIf="expedited" class="top">
                <span class="order_title">出品台详情</span>
            </div>
            <div class="content deliver_orders_container">
                <div class="content_detail">
                    <y-scrollable-container (change)="PagingMeaageChange($event)">                        
                        <div *ngIf="!expeditionOrder || !expeditionOrder.items.length" class="center">请选择菜品</div>
                        <ul class="item">                            
                                <div *ngFor="let item of result | groupedItemsTransform;trackBy:trackById">
                                    <li class="deliver_order_title" *ngIf="item.type=='category'">
                                        <span class="item_name">{{item.name}}</span>
                                    <li>
                                    <li item class="deliver_order_item" *ngIf="item.type!='category'">
                                        <suspended-orderitem  [orderItem]="item" [addDeleteBtn]="!expedited"  [order]="order" (removeItem)="removeOrderItem(item)"></suspended-orderitem>
                                    </li>
                                </div>                             
                        </ul>
                    </y-scrollable-container>
                </div>                
                <div class="bottom layout-row">
                    <div class="flex" >
                        <page-btn [btnType]="'up-down'" [upNum]="pagingInfo&&pagingInfo.previousCount"  [downNum]="pagingInfo&&pagingInfo.nextCount"  (onUp)="up()" (onDown)="down()"></page-btn>
                    </div>
                    <button  [class.active-color]="!zoneName" *ngIf="!expedited" style=" border-left: 1px solid #999999;width:40%;font-size: 20px;background:white;display:inline-block;" (click)="platter()" >{{zoneName ?  '取消':'拼盘'}}</button>
                    <button  [class.active-color]="!zoneName" *ngIf="expedited" style=" border-left: 1px solid #999999;width:40%;font-size: 20px;background:white;display:inline-block;" (click)="cancelExpeditor(expeditionOrder)" >取消出品</button>
                </div>
            </div>
            <div class="bottom check_out_btn" *ngIf="!expedited" (click)="deliver(expeditionOrder)">
                出品 <span style="font-size: 20px;">{{allItemCount}}菜</span> 
            </div>
            <div class="bottom check_out_btn" *ngIf="expedited" (click)="rePrint()">
                重新打印 <span style="font-size: 20px;">{{allItemCount}}菜</span> 
            </div>
        </div>
    `
})
export class DeliverOrders implements OnInit, OnDestroy, OnChanges {
    zoneName: string

    @Input() expeditionOrder: ExpeditionOrder;
    @Output() zoneNameChange = new EventEmitter<string>();

    constructor(
        private navSvr: NavigateService,
        private appStore: AppStore,
        private changeDetectorRef: ChangeDetectorRef,
        private storeSvr: StoreSvr,
        private printComponentService: PrintComponentService,
        private printerManager: PrinterManager
    ) { }

    ngOnDestroy(): void {
        this.subscriptions.forEach(subscription => {
            subscription.unsubscribe();
        })
    }

    get allItemCount() {
        const count = this.expeditionOrder ? this.expeditionOrder.items.map(x => x.qty - (x.refundQty || 0)).reduce((x, y) => x + y, 0) : 0;
        return count;
    }

    get expedited() {
        return location.href.includes("inished")
    }

    subscriptions: Subscription[] = [];
    @ViewChild(YScrollableContainer)
    private yScrollableContainer: YScrollableContainer;
    pagingInfo: {
        previousCount: number, nextCount: number, turningPage(count)
    }
    private trackById(index: number, order: any) {
        return order.id;
    }
    private trackByKey(index: number, order: any) {
        return order.id;
    }
    PagingMeaageChange(event) {
        this.pagingInfo = event;
    }

    platter() {
        if (this.zoneName) {
            this.zoneName = "";
        } else {
            const firstItemExtended = this.expeditionOrder && this.expeditionOrder.items[0] && this.expeditionOrder.items[0].extended;
            const zoneName = firstItemExtended && firstItemExtended.table && firstItemExtended.table.zone && firstItemExtended.table.zone.name;
            if (!zoneName) return;
            this.zoneName = zoneName;
        }
        this.zoneNameChange.emit(this.zoneName)
    }

    get result() {
        const groupBykitchenOrderId = groupBy((expeditionOrderItem: ExpeditionOrderItem) => {
            return expeditionOrderItem.customerIdentity;
        });
        const result = this.expeditionOrder && groupBykitchenOrderId(this.expeditionOrder.items);
        return result;
    }

    ngOnChanges(changes) {
        if (changes.expeditionOrder) {
            this.changeDetectorRef.detectChanges(); //todo 为什么不能加
            this.yScrollableContainer && this.yScrollableContainer.childrenChanged();
        }
    }

    ngOnInit() {
    }

    ngAfterViewInit() {

    }

    private up() {
        this.pagingInfo.turningPage(-1);
    }

    private down() {
        this.pagingInfo.turningPage(1);
    }

    async removeOrderItem(item: ExpeditionOrderItem) {
        this.navSvr.onViewDetails(item.kitchenOrderId);
        await delay(500);
        ExpeditionOrderDishManage.current.removeExpeditionOrderItem(item);
    }

    @OperationLock()
    @HandleExpectionErrorUseGrowMessage()
    async deliver(expeditionOrder) {
        if (expeditionOrder.items.length == 0) {
            return;
        }
        if (this.expeditionOrder.items.some(item => Boolean(item.refundQty))) {
            throw new Error("出品盘中有退菜，不能出品")
        }
        const retOrder = await this.appStore.orderStore.actions.deliverOrder(expeditionOrder);
        await this.print(retOrder);
        await delay(100)
        this.platter();
    }

    @Throttle(3000)
    rePrint() {
        if (this.expeditionOrder && this.expeditionOrder.items.length) {
            FNCManager.Current.expeditionPrintNotify(this.expeditionOrder);
            this.print(this.expeditionOrder);
        }
    }

    async print(expeditionOrder) {
        let orderList = this.splitExpeditionOrder(expeditionOrder);
        orderList.forEach(async (order) => {
            if (order && order.items.length) {
                if (order.extend && order.extend.QRCodePrinted) {
                    let newCode = document.createElement('img');
                    let options = {
                        displayValue: false,
                        width: 5,
                        format: 'EAN8'
                    }
                    JsBarcode(newCode, this.pad(this.expeditionOrder.serialNo, 7), options);//原生
                    order.codePic = newCode.getAttribute('src');
                }
                let printers = this.printerManager.getAllDevices();
                let store = this.storeSvr.CurrentStore;
                let printParams = {
                    token: this.storeSvr.Token,
                    store: store,
                    preOrder: order,
                    isTestPrint: false,
                    printers: printers
                }
                let res: any = await this.printComponentService.show(printParams);
                res.forEach((r) => {
                    let printResult = this.printerManager.printHtml(r);
                })
            }
        })
    }

    @HandleExpectionErrorUseGrowMessage()
    async cancelExpeditor(expeditionOrder) {
        if (!(expeditionOrder && expeditionOrder.id)) return
        let result = await MessageBoxService.current.Show("取消出品", "确认取消本次出品？");
        if (result == MessageResult.Ok) {
            await this.appStore.orderStore.actions.cancelDeliverOrder(expeditionOrder);
            await delay(100);
            this.navSvr.navigate(["newHome"]);
        }
    }

    pad(num, n) {
        var len = num.length;
        while (len < n) {
            num = "0" + num;
            len++;
        }
        return num;
    }

    splitExpeditionOrder(order) {
        var newOrders = [];
        var itemGroups = lodash.groupBy(order.items, 'customerIdentity')
        for (let i in itemGroups) {
            var newOrder = lodash.clone(order);
            newOrder.customerIdentity = i
            newOrder.items = itemGroups[i]
            //菜品列表的最早下单时间
            newOrder.orderedTime = this.getMinOrderedTimeFromItems(newOrder.items)
            newOrders.push(newOrder)
        }
        return newOrders;
    }

    getMinOrderedTimeFromItems(items) {
        var receivedTimes = [];
        items.forEach(function (item) {
            if (item.extended && item.extended.receiveTime) {
                receivedTimes.push(item.extended.receiveTime)
            }
        })
        return lodash.min(receivedTimes)
    }

}


